﻿
namespace n_MyObjectList
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using n_GUIcoder;
using n_ImagePanel;
using n_HardModule;
using n_MyObject;
using n_UIModule;
using n_GVar;
using n_GUIset;
using n_Shape;
using n_MyFileObject;
using n_MyControl;
using n_MyIns;
using n_OS;
using n_MidPortList;
using System.Collections;

//*****************************************************
//组件列表类
public class MyObjectList
{
	public delegate void D_AddModule( MyObject o );
	public D_AddModule AddModule;
	public delegate void D_ClearModule();
	public D_ClearModule ClearModule;
	
	public bool ShowStartMes;
	public MyObject[] ModuleList;
	public int MLength;
	
	Pen MouseLineBackPen;
	Pen MouseLineForePen;
	
	Pen SelectInterfacePen;
	
	public MyObject MouseOnObject;
	public MyObject ClientPad;
	
	public Port MouseOnPort;
	public Port SelectPort;

	public IPort MouseOnIPort;
	public IPort SelectIPort;
	
	
	public MyIns TipIns;
	
	
	public MyObject NewObject;
	
	public int MouseOnBaseX, MouseOnBaseY;
	
	const int PortR = 3;
	const int Port2R = PortR * 2 + 1;
	
	const int ZWireR = 10;
	const int ZWire2R = ZWireR * 2 + 1;
	
	public ResourceList myResourceList;
	
	public int RunNumber;
	
	public string Language;
	
	//绘图控件的坐标,用于右键菜单位置修正
	Point Location;
	
	public ImagePanel GPanel;
	
	//偏移坐标列表
	public AutoLocation[] AutoLocationList;
	int AutoLocationLength;
	UIModule SourceUIModule;
	
	Pen AutoLocationPenBlack;
	Pen AutoLocationPenWhite;
	Pen AutoLocationPenBlack0;
	Pen AutoLocationPenWhite0;
	
	Pen SimInsPen;
	Brush SimInsBrush;
	
	Brush LineMapBrush;
	Brush PortMapBrush;
	
	UIModule Form;
	
	public int ShowPanelTime;
	public const int ShowPanelMaxTime = 5;
	
	public UIModule LastUIModule;
	
	//添加模块时是否显示模块提示
	public bool ShowMessage;
	
	const int Offset = 2;
	
	Brush ActiveBrush;
	
	//此列表对象是否用于组件库 - 用于开关导线预连接等等
	public bool isModuleLib;
	
	//SolidBrush FloatBrush;
	
	public bool NeedDrawLineMap;
	
	//初始化
	public MyObjectList( ImagePanel g )
	{
		GPanel = g;
		
		LastUIModule = null;
		
		SourceUIModule = null;
		AutoLocationList = new AutoLocation[ 1000 ];
		AutoLocationLength = 0;
		
		System.Drawing.Drawing2D.AdjustableArrowCap AutoAC = new AdjustableArrowCap( 3, 4, true );
		
		AutoLocationPenBlack = new Pen( Color.DarkGreen, 1 );
		AutoLocationPenBlack.CustomEndCap = AutoAC;
		AutoLocationPenBlack.CustomStartCap = AutoAC;
		AutoLocationPenBlack.DashStyle = DashStyle.Dash;
		AutoLocationPenBlack.DashPattern = new float[]{3,3};
		
		AutoLocationPenWhite = new Pen( Color.LightGreen, 1 );
		AutoLocationPenWhite.CustomEndCap = AutoAC;
		AutoLocationPenWhite.CustomStartCap = AutoAC;
		AutoLocationPenWhite.DashStyle = DashStyle.Dash;
		AutoLocationPenWhite.DashOffset = 3;
		AutoLocationPenWhite.DashPattern = new float[]{3,3};
		
		AutoLocationPenBlack0 = new Pen( Color.DarkBlue, 1 );
		//AutoLocationPenBlack0.DashStyle = DashStyle.Dash;
		//AutoLocationPenBlack0.DashPattern = new float[]{3,3};
		
		AutoLocationPenWhite0 = new Pen( Color.Yellow, 1 );
		//AutoLocationPenWhite0.DashOffset = 3;
		//AutoLocationPenWhite0.DashStyle = DashStyle.Dash;
		//AutoLocationPenWhite0.DashPattern = new float[]{3,3};
		
		ActiveBrush = new SolidBrush( Color.FromArgb( 220, 200, 100, 100 ) );
		
		LineMapBrush = new SolidBrush( Color.FromArgb( 100, Color.Yellow ) );
		PortMapBrush = new SolidBrush( Color.FromArgb( 100, Color.CornflowerBlue ) );
		
		SimInsPen = new Pen( Color.OrangeRed, 3 );
		SimInsBrush = new SolidBrush( Color.FromArgb( 80, Color.OrangeRed ) );
		
		//FloatBrush = new SolidBrush( Color.FromArgb( 100, 0, 0, 0 ) );
		
		NeedDrawLineMap = true;
		
		Location = new Point( 5, 25 );
		Language = null;
		MouseOnPort = null;
		SelectPort = null;
		
		MouseOnIPort = null;
		SelectIPort = null;
		
		NewObject = null;
		
		MouseOnBaseX = 0;
		MouseOnBaseY = 0;
		
		TipIns = null;
		
		ShowMessage = false;
		
		isModuleLib = false;
		ShowStartMes = true;
		
		myResourceList = new ResourceList();
		
		System.Drawing.Drawing2D.AdjustableArrowCap AC = new AdjustableArrowCap( 5, 4, true );
		
		if( n_MainSystemData.SystemData.isBlack ) {
			MouseLineBackPen = new Pen( Color.Yellow, 3 );
		}
		else {
			MouseLineBackPen = new Pen( Color.DarkOrange, 3 );
		}
		
		MouseLineBackPen.DashStyle = DashStyle.Dot;
		MouseLineBackPen.CustomStartCap = AC;
		MouseLineForePen = new Pen( Color.Green, 1 );
		MouseLineForePen.DashStyle = DashStyle.Dot;
		
		if( n_MainSystemData.SystemData.isBlack ) {
			SelectInterfacePen = new Pen( Color.Yellow, 3 );
		}
		else {
			SelectInterfacePen = new Pen( Color.DarkOrange, 3 );
		}
		
		SelectInterfacePen.DashStyle = DashStyle.Dot;
		
		ModuleList = new MyObject[ 2000 ];
		MLength = 0;
		
		RunNumber = 0;
	}
	
	//迭代器
	public bool IterReverse = false;
	public IEnumerator GetEnumerator()
	{
		if( IterReverse ) {
			for (int index = MLength - 1; index >= 0; index--) {
				if( ModuleList[index] == null ) {
					continue;
				}
				yield return ModuleList[index];
			}
		}
		else {
			for (int index = 0; index < MLength; index++) {
				if( ModuleList[index] == null ) {
					continue;
				}
				yield return ModuleList[index];
			}
		}
	}
	
	//清空组件列表
	public void Clear()
	{
		Form = null;
		
		//遍历组件列表,查找所有指向目标组件的链接,如果存在则提示是否删除
		for( int i = 0; i < MLength; ++i ) {
			ModuleList[ i ] = null;
		}
		if( ClearModule != null ) {
			ClearModule();
		}
		MLength = 0;
	}
	
	//判断一个名字是否被使用
	public bool NameisUsed( string Name )
	{
		foreach( MyObject mo in this ) {
			
			//判断是否是用户定义函数 以及遍历形参
			if( mo is n_UserFunctionIns.UserFunctionIns ) {
				string[] c = ((n_UserFunctionIns.UserFunctionIns)mo).GetVarList();
				for( int n = 0; c != null && n < c.Length; ++n ) {
					if( c[n] == Name ) {
						return true;
					}
				}
			}
			//任何元素都要判断名字 包括自定义函数
			if( mo.Name == Name ) {
				return true;
			}
		}
		return false;
	}
	
	//把一个模块放到最上层(暂时未用)
	void SendToFront( MyObject cModule )
	{
		int Index = 0;
		for( Index = 0; Index < ModuleList.Length; ++Index ) {
			if( ModuleList[Index] == cModule ) {
				break;
			}
		}
		for( int i = Index; i < ModuleList.Length - 1; ++i ) {
			ModuleList[i] = ModuleList[i+1];
		}
		for( int i = Index; i < ModuleList.Length - 1; ++i ) {
			if( ModuleList[i] == null ) {
				ModuleList[i] = cModule;
				break;
			}
		}
	}
	
	//添加组件
	public void Add( MyObject cModule )
	{
		if( AddModule != null ) {
			AddModule( cModule );
		}
		
		//判断是否需要设置提示信息
		if( ShowStartMes && !isModuleLib && cModule is HardModule ) {
			HardModule mf = (HardModule)cModule;
			
			string partPath = mf.MacroFilePath.Remove( 0, OS.ModuleLibPath.Length );
			
			//判断模块是否过时
			if( mf.PackOwner == null && n_ModuleLibDecoder.ModuleLibDecoder.isOld( partPath ) ) {
				string InsMes = "重要提示： 此模块已经过时, 建议您删除此模块, 然后在模块列表中找到升级版或者相似的模块重新添加一次. 另外替换新模块后, 跟此模块相关的程序指令可能也需要重新编辑和设置";
				GPanel.AddMesPanel( InsMes, 3, cModule );
			}
			
			//SH1106 12864液晶屏IO口需要接上限流电阻
			if( mf.MacroFilePath == OS.ModuleLibPath + @"common\SH1106_12864\Pack.B" ) {
				string InsMes = "重要提示： 目前有些12864液晶屏的端口电压为3.3V, 因此不能直接接到arduino IO端口上,";
				InsMes += "推荐的方案是模块的4个信号线 (CLK,CS,SI,DC, 不含电源线) 各通过一个限流电阻(1K欧姆即可)再连接到主控板的端口, 不接限流电阻的话, 屏幕可能不稳定, 经常花屏. 电源线可根据屏幕输入电压规范接到arduino的5V或者3.3V输出端口.";
				GPanel.AddMesPanel( InsMes, 3, cModule );
			}
			
			//AD转换类模块需要加上下拉电阻
			if( mf.MacroFilePath == OS.ModuleLibPath + @"Arduino\LightR\Pack.B" ||
			    mf.MacroFilePath == OS.ModuleLibPath + @"Arduino\ADtemprature\Pack.B" ||
			    mf.MacroFilePath == OS.ModuleLibPath + @"input\SoundAD\Module.M" ||
			    mf.MacroFilePath == OS.ModuleLibPath + @"common\TuRang\Pack.B" ||
			    mf.MacroFilePath == OS.ModuleLibPath + @"common\YuDi\Pack.B" ) {
				string InsMes = 
						 "重要提示： 此模块为AD模拟量信号输出, 必须要外接一个下拉电阻. 模块和下拉电阻串联后, 中间抽头引出来接到主板的模拟量输入接口, 模块和电阻的另外两端分别接到电源正极和负极. 下拉电阻的阻值范围一般为10K欧姆(10000)";
				GPanel.AddMesPanel( InsMes, 3, cModule );
			}
			
			/*
			//分压电阻需要从电阻端开始接线
			if( mf.MacroFilePath == OS.ModuleLibPath + @"Arduino\RegisterPULL\Register.B" ) {
				string InsMes = 
						 "要连接分压电阻, 请先从分压电阻的端口开始点击连接到其他元件的端口. 尽量避免从其他元件连接到分压电阻, 因为点击其他元件的从端口会删除当前连线, 给用户带来不便";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			*/
			
			//LED类元件需要加上限流电阻
			if( mf.MacroFilePath.StartsWith( OS.ModuleLibPath + @"output\LED_F\" ) ) {
				string InsMes = 
						 "LED指示灯元件发光时所需的电流约为10mA左右, 所以不能直接把LED连接到端口上, 而是需要串联一个限流电阻(不加电阻可能会烧坏LED). 限流电阻数值一般可在560欧姆左右自行选择. 阻值越小, 光线越亮. 由于绿色LED材质原因会比较暗, 可适当降低限流电阻值提高亮度.";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			
			//I2C接口的液晶屏地址需要提示
			if( mf.MacroFilePath == OS.ModuleLibPath + @"Arduino\lcd1602PCF8574\Pack.B" || mf.MacroFilePath == OS.ModuleLibPath + @"Arduino\lcd2004PCF8574\Pack.B" ) {
				string InsMes = 
						 "重要提示： 默认地址为0, 表示自动搜索地址! 一般不需要改. (PCF8574T对应的地址为0x27; PCF8574AT对应的地址为0x3F). 如果屏幕不显示, 请尝试调节屏幕转接板上的对比度电阻, 阻值调节适中, 屏幕才会显示出清晰的字符.";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			
			
			//点阵字符显示器需要设置字体
			if( mf.MacroFilePath == OS.ModuleLibPath + @"engine\GUIchar1\Pack.B" ) {
				string InsMes = "点阵字符显示器可以在点阵屏幕上显示点阵字体文字, 除了使用内置的字体外, 您也可以拖进来自定义的字体模块, 编辑字体, 并在显示信息之前通过设置字体指令给点阵字符显示器设置新字体";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			if( mf.MacroFilePath == OS.ModuleLibPath + @"software\soft_delayer\delayer.B" ) {
				string InsMes = "高精度延时器是高手专用! 本模块延时期间会阻塞系统调度, 除非是有必要, 否则尽量不要用高精度延时器. 另外如需使用本模块, 建议配合系统主控模块实现, 详细用法见本模块示例";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			/*
			if( mf.MacroFilePath == OS.ModuleLibPath + @"software\delayer\delayer.B" ) {
				
				foreach( MyObject mo in this ) {
					if( !(mo is HardModule) ) {
						continue;
					}
					HardModule hm = (HardModule)mo;
					if( hm.MacroFilePath == OS.ModuleLibPath + @"software\delayer\delayer.B" ) {
						string InsMes =
						 	"延时器模块基于系统内置的事件调度系统而工作, 整个界面中只需要有一个延时器即可, 如果之前已存在延时器, 那么您不需要再拖进多个. 您可以随时在任何事件中调用延时指令, 而其他多个事件中" +
							"正在执行的延时指令不受影响. 通常系统可以保证至少5个延时指令同时延时(取决于调度系统配置). 如果多于5个同时延时的话, 那么系统将会暂停其中一个延时, " +
							"直到其他5个延时指令中某一个执行完, 腾出了空闲的进程池.";
						MessageBox.Show( InsMes, "模块添加无效提示" );
						//return;
					}
				}
				
				//string InsMes =
				//		 "延时器模块基于系统内置的事件调度系统而工作, 整个界面中只需要有一个延时器即可, 如果之前已存在延时器, 那么您不需要再拖进多个. 您可以随时在任何事件中调用延时指令, 而其他多个事件中" +
				//		 "正在执行的延时指令不受影响. 通常系统可以保证至少5个延时指令同时延时(取决于调度系统配置). 如果多于5个同时延时的话, 那么系统将会暂停其中一个延时, " +
				//		 "直到其他5个延时指令中某一个执行完, 腾出了空闲的进程池.";
				//GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			*/
			
			if( mf.MacroFilePath == OS.ModuleLibPath + @"engine\Motor_PWM\Motor_PWM.B" ) {
				string InsMes =
					"马达只要加上了这个转速调速器，就不能再使用原来马达的任何指令了，比如正反转，即使使用了这些指令，也会瞬间被调速器冲掉，因为调速器根据自身设置的转速，在无时无刻的控制着马达，马达自身的正反转指令不会起到任何作用. " +
					"如果需要马达正反转，只能通过设置调速器的转速来实现，100是最大速度正转，-100是最大速度反转. 其他数值对应相应的转速, 设置为0可让马达停下来.";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			if( mf.MacroFilePath == OS.ModuleLibPath + @"software\SOFT_UART\UART.B" ) {
				string InsMes =
					"通过此模块可以让arduino的任意两个端口模拟成一个软件串口，注意波特率不要设置太大，最高支持57600波特率稳定收发数据，再高的话，就会出现乱码了。由于是软件模拟，所以不支持串口数据接收中断，只能通过“等待并接收一个数据”来进行接收，此时其他程序是阻塞的。";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
			if( mf.MacroFilePath == OS.ModuleLibPath + @"labrobot\common\NRF2401\Pack.B" ) {
				string InsMes =
						 "此型号的无线遥控器, 每个都有自己专属的ID(在遥控器背面有标注), 请设置图形界面中此遥控器的ID, 确保和您手中的实物遥控器ID一致. 如果ID不一致的话, 则无法实现对小车的遥控.";
				GPanel.AddMesPanel( InsMes, 1, cModule );
			}
		}
		
		if( cModule is UIModule &&((UIModule)cModule).isClientControlPad ) {
			ClientPad = cModule;
		}
		for( int i = 0; i < ModuleList.Length; ++i ) {
			if( ModuleList[ i ] == null ) {
				ModuleList[ i ] = cModule;
				cModule.Index = i;
				cModule.myObjectList = this;
				if( MLength <= i ) {
					MLength = i + 1;
				}
				return;
			}
		}
		MessageBox.Show( "<MyObjectList Add> 组件列表已满 - 系统发生了一个严重的问题, 请您将此错误报告给linkboy开发团队, 以便尽快解决此软件BUG, 谢谢!" );
	}
	
	//在最底层加入模块(仅用于面包板) 调整面包板的位置, 放到所有控件的最前边
	public void Addmbb( MyObject cModule )
	{
		MLength++;
		for( int i = MLength - 2; i >= 0; --i ) {
			ModuleList[i+1] = ModuleList[i];
			if( ModuleList[i+1] != null ) {
				ModuleList[i+1].Index = i+1;
			}
		}
		ModuleList[0] = cModule;
		cModule.Index = 0;
		cModule.myObjectList = this;
		
		/*
		if( cModule is HardModule && ((HardModule)cModule).ImageName == n_GUIcoder.SPMoudleName.SYS_Arduino ) {
			((HardModule)cModule).PackHid = true;
			((HardModule)cModule).CanFloat = true;
			cModule.Visible = false;
			cModule.GroupVisible = false;
		}
		*/
	}
	
	//调整ControlPad的位置, 放到所有控件的最前边
	public void AddFirst( MyObject cModule )
	{
		MLength++;
		for( int i = MLength - 2; i >= 0; --i ) {
			ModuleList[i+1] = ModuleList[i];
			if( ModuleList[i+1] != null ) {
				ModuleList[i+1].Index = i+1;
			}
		}
		ModuleList[0] = cModule;
		cModule.Index = 0;
		cModule.myObjectList = this;
		Form = (UIModule)cModule;
		ClientPad = cModule;
	}
	
	//根据名称获取组件
	public MyObject GetModuleFromName( string Name )
	{
		foreach( MyObject mo in this ) {
			if( mo.Name == Name ) {
				return mo;
			}
		}
		return null;
	}
	
	//封包
	public void Pack( string HidMes )
	{
		bool PackOpenMPort = false;
		if( HidMes.IndexOf( PackHidType.SYS_OPEN_MPORT ) != -1 ) {
			PackOpenMPort = true;
		}
		
		foreach( MyObject mo in this ) {
			
			if( !mo.isSelect ) {
				continue;
			}
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule h = (HardModule)mo;
			
			h.PackOpenMPort = PackOpenMPort;
			if( HidMes.IndexOf( "," + h.Name + "," ) != -1 ) {
				h.PackOwner = PackHidType.hid + ",";
				h.PackHid = true;
				h.CanFloat = true;
			}
			else {
				h.PackOwner = PackHidType.nohid + ",";
			}
			//设置端口连接属性
			if( PackOpenMPort ) {
				h.PackOwner += PackHidType.SYS_OPEN_MPORT + ",";
			}
			else {
				h.PackOwner += "default,";
			}
		}
	}
	
	//解封
	public void UnPack()
	{
		foreach( MyObject mo in this ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule h = (HardModule)mo;
			h.PackOwner = null;
			h.PackHid = false;
			h.GroupVisible = true;
		}
	}
	
	//遍历模块列表并更新分组列表
	public void RefreshGroup( n_GroupList.GroupList gl )
	{
		gl.Reset();
		
		foreach( MyObject mo in this ) {
			if( mo.GroupMes != null ) {
				gl.Refresh( mo );
			}
		}
		
		gl.DeleteNull();
	}
	
	//-----------------------------------------
	
	//初始化各个模块的仿真数据表
	public void ResetSim()
	{
		foreach( MyObject mo in this ) {
			if( (mo is HardModule) ) {
				HardModule hm = (HardModule)mo;
				hm.ResetSim();
			}
			if( (mo is GVar) ) {
				GVar hm = (GVar)mo;
				hm.ResetSim();
			}
			if( (mo is MyIns) ) {
				MyIns hm = (MyIns)mo;
				hm.ResetSim();
			}
			mo.ResetSimBase();
		}
	}
	
	//停止模块的仿真
	public void StopSim()
	{
		foreach( MyObject mo in this ) {
			if( !(mo is HardModule) ) {
				continue;
			}
			HardModule hm = (HardModule)mo;
			hm.StopSim();
		}
	}
	
	//-----------------------------------------
	
	//绘图函数
	public void DrawImage( Graphics g )
	{
		if( MyObject.PasteMoveTime != 0 ) {
			MyObject.PasteMoveTime--;
			GPanel.MyRefresh();
		}
		
		//绘制基本组件
		foreach( MyObject mo in this ) {
			
			//判断是否需要移动 (这里要放到前边, 因为指令隐藏时或者折叠状态下, 也是需要自动移动的
			if( mo.NeedPasteMove ) {
				mo.SX -= 2;
				if( MyObject.PasteMoveTime == 0 ) {
					mo.NeedPasteMove = false;
				}
			}
			
			if( !mo.isVisible() ) {
				continue;
			}
			mo.Draw1( g );
		}
		//绘制所有链接导线
		foreach( MyObject mo in this ) {
			if( !mo.isVisible() ) {
				
				if( !mo.GroupVisible && mo is HardModule ) {
					HardModule h = (HardModule)mo;
					h.AutoConnectInterface();
					h.DrawInterfaceLine( g );
				}
				if( !mo.GroupVisible && mo is n_UserFunctionIns.UserFunctionIns ) {
					n_UserFunctionIns.UserFunctionIns h = (n_UserFunctionIns.UserFunctionIns)mo;
					h.DrawEventLine( g );
				}
				
				continue;
			}
			mo.Draw2( g );
		}
		/*
		//绘制阴影
		if( G.SimulateMode ) {
			g.FillRectangle( FloatBrush, -1, -1, G.CGPanel.Width, G.CGPanel.Height );
		}
		*/
		
		
		if( NeedDrawLineMap ) {
			n_ImagePanel.ImagePanel.gl.Clear( Color.White );
		}
		
		//绘制所有组件端口
		foreach( MyObject mo in this ) {
			if( !mo.isVisible() ) {
				continue;
			}
			mo.Draw3( g );
			
			//更新导线轨迹图
			if( NeedDrawLineMap ) {
				if( mo is HardModule ) {
					HardModule hhh = (HardModule)mo;
					hhh.DrawLineIndex( n_ImagePanel.ImagePanel.gl );
				}
			}
			//绘制指令仿真的边框
			if( mo is MyIns ) {
				MyIns mi = (MyIns)mo;
				if( mi.isActive() ) {
					if( mi.PreIns == null || !mi.PreIns.isActive() ) {
						
						if( !mi.isNote ) {
							g.DrawRectangle( SimInsPen, mo.SX, mo.SY, mo.Width, mo.Height );
							//g.FillEllipse( Brushes.Yellow, StartX + ModuleList[ i ].SX - ModuleList[i].Height, StartY + ModuleList[ i ].SY, ModuleList[i].Height, ModuleList[i].Height );
						}
						
						mo.DataList[2] -= 1;
					}
					G.CGPanel.MyRefresh();
				}
				//绘制指令延时时间
				if( G.SimulateMode && mi.GetTime() > 0 && mi.GetTotalTime() != 0 ) {
					int t = mi.GetTime() * mo.Width / mi.GetTotalTime();
					g.DrawRectangle( SimInsPen, mo.SX, mo.SY, mo.Width, mo.Height );
					g.FillRectangle( SimInsBrush, mo.SX, mo.SY, t, mo.Height );
					g.DrawString( mi.GetTime() + "ms", n_GUIset.GUIset.Font11, Brushes.DarkRed,  mo.SX + mo.Width + 3 , mo.SY - 4 );
					g.DrawString( mi.GetTotalTime() + "ms", n_GUIset.GUIset.Font11, Brushes.DimGray,  mo.SX + mo.Width + 3 , mo.SY + mo.Height / 2 - 1 );
					G.CGPanel.MyRefresh();
				}
			}
		}
		
		//绘制仿真元素
		foreach( MyObject mo in this ) {
			
			if( !mo.isVisible() ) {
				continue;
			}
			mo.DrawSim( g );
		}
		
		/*
		//当有选中的组件时, 灰色显示其他的组件
		if( GPanel != null && GPanel.SelPanel.SelectListLength != 0 && GPanel.SelPanel.SelectState != 0 ) {
			g.FillRectangle( GUIset.HideBackBrush, 0, 0, GPanel.Width, GPanel.Height );
			
			//绘制所有组件高亮选中
			for( int i = 0; i < ModuleList.Length; ++i ) {
				if( ModuleList[ i ] == null ) {
					continue;
				}
				if( !ModuleList[ i ].isSelect ) {
					continue;
				}
				ModuleList[ i ].Draw1( g, StartX, StartY );
				ModuleList[ i ].Draw2( g, StartX, StartY );
				ModuleList[ i ].Draw3( g, StartX, StartY );
			}
		}
		*/
		
		//绘制自动吸附列表
		DrawAutoLocationList( g );
		
		//绘制鼠标悬停端口
		if( MouseOnPort != null ) {
			MouseOnPort.DrawHighLight( g );
		}
		//绘制鼠标悬停接口
		if( !isModuleLib && MouseOnIPort != null ) {
			MouseOnIPort.DrawHighLight( g );
		}
		//绘制选中端口
		if( SelectPort != null ) {
			SelectPort.DrawSelect( g );
		}
		//绘制选中端口的链接导线
		if( SelectPort != null ) {
			PointF PA = new PointF( MouseOnBaseX, MouseOnBaseY );
			PointF PB = new PointF( SelectPort.Owner.MidX + SelectPort.X, SelectPort.Owner.MidY + SelectPort.Y );
			
			float Xlength = Math.Abs( PA.X - PB.X );
			float Ylength = Math.Abs( PA.Y - PB.Y );
			float Length = (float)Math.Sqrt( Xlength * Xlength + Ylength * Ylength );
			float Rol = Length * n_HardModule.Port.C_Rol / 100;
			
			if( SelectPort.MidPortIndex != -1 && n_HardModule.Port.C_Rol != 0 ) {
				Rol = 50;
			}
			PointF PA1;
			if( MouseOnPort != null ) {
				PA1 = Port.GetDirPoint( Rol, PA, MouseOnPort.DirType );
			}
			else {
				PA1 = new PointF( PA.X, PA.Y );
			}
			PointF PB1 = Port.GetDirPoint( Rol, PB, SelectPort.DirType );
			
			
			MouseLineBackPen.Color = PortPenList.BackLinePen[SelectPort.ColorIndex].Color;
			MouseLineForePen.Color = PortPenList.ForeLinePen[SelectPort.ColorIndex].Color;
			
			
			if( SelectPort.MidPortIndex == -1 ) {
				g.DrawBezier( MouseLineBackPen, PA, PA1, PB1, PB );
				g.DrawBezier( MouseLineForePen, PA, PA1, PB1, PB );
				//g.DrawBezier( MouseLineForePen, PA, PA1, PB1, PB );
			}
			else{
				int CLength = G.CGPanel.myMidPortList.GetLength( SelectPort.MidPortIndex );
				PointF[] pp = new PointF[4+CLength*3];
				pp[0] = PB;
				pp[1] = PB1;
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = GPanel.myMidPortList.GetPoint( SelectPort.MidPortIndex, i );
					PointF PO = new PointF( p.X, p.Y );
					pp[2 + i * 3 + 1] = PO;
				}
				pp[2+CLength*3] = PA1;
				pp[3+CLength*3] = PA;
				
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = GPanel.myMidPortList.GetPoint( SelectPort.MidPortIndex, i );
					
					PointF PO = new PointF( p.X, p.Y );
					
					float ox = pp[2 + i * 3 + 4].X - pp[2 + i * 3 - 2].X;
					float oy = pp[2 + i * 3 + 4].Y - pp[2 + i * 3 - 2].Y;
					ox /= 7;
					oy /= 7;
					if( n_HardModule.Port.C_Rol == 0 ) {
						ox = 0;
						oy = 0;
					}
					
					PointF PO1 = new PointF( p.X - ox, p.Y - oy );
					PointF PO2 = new PointF( p.X + ox, p.Y + oy );
					
					pp[2 + i * 3] = PO1;
					pp[2 + i * 3 + 2] = PO2;
					
					//g.FillRectangle( Brushes.SlateGray, PO.X, PO.Y, 4, 4 );
					
					//g.FillRectangle( Brushes.Red, PO1.X, PO1.Y, 4, 4 );
					//g.FillRectangle( Brushes.Blue, PO2.X, PO2.Y, 4, 4 );
				}
				if( n_HardModule.Port.C_Rol != 0 ) {
					g.DrawBeziers( MouseLineBackPen, pp );
					g.DrawBeziers( MouseLineForePen, pp );
				}
				else {
					g.DrawLines( MouseLineBackPen, pp );
					g.DrawLines( MouseLineForePen, pp );
				}
			}
		}
		//绘制选中的接口
		if( SelectIPort != null ) {
			Shape.DrawEngineLine( g, SelectInterfacePen,
			                         SelectIPort.Owner.MidX + SelectIPort.MidX,
			                         SelectIPort.Owner.MidY + SelectIPort.MidY,
			                         MouseOnBaseX,
			                         MouseOnBaseY );
		}
		//绘制新组件
		
		foreach( MyObject mo in this ) {
			if( mo is n_MyFileObject.MyFileObject && mo.ignoreHit ) {
				mo.Draw1( g );
				mo.Draw2( g );
				mo.Draw3( g );
			}
		}
		//绘制目标指令
		if( TipIns != null ) {
			TipIns.DrawHighLight( g );
		}
		//绘制移动的指令
		foreach( MyObject mo in this ) {
			if( mo.isVisible() && mo is MyIns && ((MyIns)mo).isMoving ) {
				mo.Draw1( g );
				mo.Draw2( g );
				mo.Draw3( g );
			}
		}
		if( !G.SimulateMode && !G.CGPanel.isMousePress && (G.CGPanel.TakeMoIndex != -1 && G.CGPanel.TakePoIndex != -1 || (n_CLineList.CLineList.ShowMesTick == 0 && G.CGPanel.CLineIndex != -1)) ) {
			if( G.CGPanel.myModuleList.SelectPort != null ) {
				g.FillRectangle( LineMapBrush, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawRectangle( Pens.DimGray, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawString( "点击左键可连接到此导线", GUIset.ModuleNameFont, Brushes.Black, MouseOnBaseX + 5 - 80, MouseOnBaseY + 5 - 80 );
			}
			else {
				g.FillRectangle( LineMapBrush, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 52 );
				g.DrawRectangle( Pens.DimGray, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 52 );
				g.DrawString( "点击左键可在导线上添加拖点", GUIset.ModuleNameFont, Brushes.Black, MouseOnBaseX + 5 - 92, MouseOnBaseY + 5 - 80 );
				g.DrawString( "点击右键可删除此导线", GUIset.ModuleNameFont, Brushes.Black, MouseOnBaseX + 5 - 72, MouseOnBaseY + 5 - 60 );
			}
		}
		else if( G.CGPanel.myMidPortList.MouseOnMidPort != null ) {
			if( G.CGPanel.myModuleList.SelectPort != null ) {
				g.FillRectangle( PortMapBrush, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawRectangle( Pens.DimGray, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawString( "点击左键可连接到此拖点", GUIset.ModuleNameFont, Brushes.Black, MouseOnBaseX + 5 - 80, MouseOnBaseY + 5 - 80 );
			}
			else {
				g.FillRectangle( PortMapBrush, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawRectangle( Pens.DimGray, MouseOnBaseX - 90, MouseOnBaseY - 80, 180, 30 );
				g.DrawString( "点击右键可删除此拖点", GUIset.ModuleNameFont, Brushes.Black, MouseOnBaseX + 5 - 72, MouseOnBaseY + 5 - 80 );
			}
		}
		else {
			//...
		}
	}
	
	//绘制高亮选中
	public void DrawHighLight( Graphics g )
	{
		//绘制所有组件高亮选中
		n_MyPanel.MyPanel.ExistPanel = false;
		foreach( MyObject mo in this ) {
			if( !mo.isHighLight ) {
				continue;
			}
			if( !mo.isVisible() ) {
				continue;
			}
			mo.DrawHighLight( g );
		}
	}
	
	//绘制自动吸附列表
	void DrawAutoLocationList( Graphics g )
	{
		if( SourceUIModule == null ) {
			return;
		}
		Pen AutoLocationPen = AutoLocationPenWhite;
		Pen AutoLocationPen0 = AutoLocationPenWhite0;
		if( Form != null && Form.BackColor.R + Form.BackColor.G + Form.BackColor.B > 128 * 3 ) {
			AutoLocationPen = AutoLocationPenBlack;
			AutoLocationPen0 = AutoLocationPenBlack0;
		}
		for( int i = 0; i < AutoLocationLength; ++i ) {
			if( !AutoLocationList[ i ].isUsed ) {
				continue;
			}
			int NearMode = AutoLocationList[ i ].NearType;
			
			UIModule NearUIModule = AutoLocationList[ i ].TargetUIModule;
			if( NearMode == AutoLocation.Near_X ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX,
				           SourceUIModule.MidY,
				           NearUIModule.SX,
				           NearUIModule.MidY );
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX,
				           SourceUIModule.SY - 20,
				           SourceUIModule.SX,
				           SourceUIModule.SY + SourceUIModule.Height + 20 );
				g.DrawLine( AutoLocationPen0,
				           NearUIModule.SX,
				           NearUIModule.SY - 20,
				           NearUIModule.SX,
				           NearUIModule.SY + NearUIModule.Height + 20 );
			}
			if( NearMode == AutoLocation.Near_XEnd ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX + SourceUIModule.Width,
				           SourceUIModule.MidY,
				           NearUIModule.SX + NearUIModule.Width,
				           NearUIModule.MidY );
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX + SourceUIModule.Width,
				           SourceUIModule.SY - 20,
				           SourceUIModule.SX + SourceUIModule.Width,
				           SourceUIModule.SY + SourceUIModule.Height + 20 );
				g.DrawLine( AutoLocationPen0,
				           NearUIModule.SX + NearUIModule.Width,
				           NearUIModule.SY - 20,
				           NearUIModule.SX + NearUIModule.Width,
				           NearUIModule.SY + NearUIModule.Height + 20 );
			}
			if( NearMode == AutoLocation.Near_Y ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.MidX,
				           SourceUIModule.SY,
				           NearUIModule.MidX,
				           NearUIModule.SY );
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX - 20,
				           SourceUIModule.SY,
				           SourceUIModule.SX + SourceUIModule.Width + 20,
				           SourceUIModule.SY );
				g.DrawLine( AutoLocationPen0,
				           NearUIModule.SX - 20,
				           NearUIModule.SY,
				           NearUIModule.SX + NearUIModule.Width + 20,
				           NearUIModule.SY );
			}
			if( NearMode == AutoLocation.Near_YEnd ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.MidX,
				           SourceUIModule.SY + SourceUIModule.Height,
				           NearUIModule.MidX,
				           NearUIModule.SY + NearUIModule.Height );
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.SX - 20,
				           SourceUIModule.SY + SourceUIModule.Height,
				           SourceUIModule.SX + SourceUIModule.Width + 20,
				           SourceUIModule.SY + SourceUIModule.Height );
				g.DrawLine( AutoLocationPen0,
				           NearUIModule.SX - 20,
				           NearUIModule.SY + NearUIModule.Height,
				           NearUIModule.SX + NearUIModule.Width + 20,
				           NearUIModule.SY + NearUIModule.Height );
			}
			//判断是否X中心线对齐
			if( NearMode == AutoLocation.Near_MidX ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.MidX,
				           SourceUIModule.MidY,
				           NearUIModule.MidX,
				           NearUIModule.MidY );
			}
			//判断是否Y中心线对齐
			if( NearMode == AutoLocation.Near_MidY ) {
				g.DrawLine( AutoLocationPen0,
				           SourceUIModule.MidX,
				           SourceUIModule.MidY,
				           NearUIModule.MidX,
				           NearUIModule.MidY );
			}
			if( NearMode == AutoLocation.Near_XOffset ) {
				g.DrawLine( AutoLocationPen, SourceUIModule.SX, SourceUIModule.MidY, NearUIModule.SX, SourceUIModule.MidY );
				g.DrawLine( AutoLocationPen,
				           AutoLocationList[ i ].UIModule1.SX, AutoLocationList[ i ].UIModule1.MidY,
				           AutoLocationList[ i ].UIModule0.SX, AutoLocationList[ i ].UIModule1.MidY );
			}
			if( NearMode == AutoLocation.Near_YOffset ) {
				g.DrawLine( AutoLocationPen, SourceUIModule.MidX, SourceUIModule.SY, SourceUIModule.MidX, NearUIModule.SY );
				g.DrawLine( AutoLocationPen,
				           AutoLocationList[ i ].UIModule1.MidX, AutoLocationList[ i ].UIModule1.SY,
				           AutoLocationList[ i ].UIModule1.MidX, AutoLocationList[ i ].UIModule0.SY );
			}
			if( NearMode == AutoLocation.Near_Width ) {
				g.DrawLine( AutoLocationPenWhite,
				           SourceUIModule.SX,
				           SourceUIModule.MidY,
				           SourceUIModule.SX + SourceUIModule.Width,
				           SourceUIModule.MidY );
				g.DrawLine( AutoLocationPenBlack,
				           SourceUIModule.SX,
				           SourceUIModule.MidY,
				           SourceUIModule.SX + SourceUIModule.Width,
				           SourceUIModule.MidY );
				
				g.DrawLine( AutoLocationPenWhite,
				           AutoLocationList[ i ].TargetUIModule.SX,
				           AutoLocationList[ i ].TargetUIModule.MidY,
				           AutoLocationList[ i ].TargetUIModule.SX + AutoLocationList[ i ].TargetUIModule.Width,
				           AutoLocationList[ i ].TargetUIModule.MidY );
				g.DrawLine( AutoLocationPenBlack,
				           AutoLocationList[ i ].TargetUIModule.SX,
				           AutoLocationList[ i ].TargetUIModule.MidY,
				           AutoLocationList[ i ].TargetUIModule.SX + AutoLocationList[ i ].TargetUIModule.Width,
				           AutoLocationList[ i ].TargetUIModule.MidY );
				
			}
			if( NearMode == AutoLocation.Near_Height ) {
				g.DrawLine( AutoLocationPenWhite,
				           SourceUIModule.MidX,
				           SourceUIModule.SY,
				           SourceUIModule.MidX,
				           SourceUIModule.SY + SourceUIModule.Height );
				g.DrawLine( AutoLocationPenBlack,
				           SourceUIModule.MidX,
				           SourceUIModule.SY,
				           SourceUIModule.MidX,
				           SourceUIModule.SY + SourceUIModule.Height );
				
				g.DrawLine( AutoLocationPenWhite,
				           AutoLocationList[ i ].TargetUIModule.MidX,
				           AutoLocationList[ i ].TargetUIModule.SY,
				           AutoLocationList[ i ].TargetUIModule.MidX,
				           AutoLocationList[ i ].TargetUIModule.SY + AutoLocationList[ i ].TargetUIModule.Height );
				g.DrawLine( AutoLocationPenBlack,
				           AutoLocationList[ i ].TargetUIModule.MidX,
				           AutoLocationList[ i ].TargetUIModule.SY,
				           AutoLocationList[ i ].TargetUIModule.MidX,
				           AutoLocationList[ i ].TargetUIModule.SY + AutoLocationList[ i ].TargetUIModule.Height );
			}
		}
	}
	
	//重新扫描坐标列表
	public void ScanLocation( UIModule s )
	{
		AutoLocationLength = 0;
		foreach( MyObject mo in this ) {
		
			if( !(mo is UIModule) ) {
				continue;
			}
			UIModule u = (UIModule)mo;
			if( s == u || !u.isGUIControl() || u.isClientControlPad ) {
				continue;
			}
			//添加单元件坐标
			AutoLocation ax = new AutoLocation( AutoLocation.Near_X );
			ax.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = ax;
			++AutoLocationLength;
			
			AutoLocation ay = new AutoLocation( AutoLocation.Near_Y );
			ay.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = ay;
			++AutoLocationLength;
			
			//添加单元件坐标(终点)
			AutoLocation axe = new AutoLocation( AutoLocation.Near_XEnd );
			axe.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = axe;
			++AutoLocationLength;
			
			AutoLocation aye = new AutoLocation( AutoLocation.Near_YEnd );
			aye.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = aye;
			++AutoLocationLength;
			
			//添加单元件XY中间线
			AutoLocation mxe = new AutoLocation( AutoLocation.Near_MidX );
			mxe.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = mxe;
			++AutoLocationLength;
			
			AutoLocation mye = new AutoLocation( AutoLocation.Near_MidY );
			mye.UIModule0 = u;
			AutoLocationList[ AutoLocationLength ] = mye;
			++AutoLocationLength;
			
			//添加间距类坐标
			foreach( MyObject m1 in this ) {
			
				if( !(m1 is UIModule) ) {
					continue;
				}
				UIModule m = (UIModule)m1;
				if( s == m || !m.isGUIControl()|| m.isClientControlPad || u == m ) {
					continue;
				}
				//检查宽度差
				int OfffsetWidth = u.SX - m.SX;
				if( OfffsetWidth != 0 && Math.Abs( u.MidX - m.MidX ) < (u.Width + m.Width) ) {
					AutoLocation a = new AutoLocation( AutoLocation.Near_XOffset );
					a.Offset = OfffsetWidth;
					a.UIModule0 = m;
					a.UIModule1 = u;
					AutoLocationList[ AutoLocationLength ] = a;
					++AutoLocationLength;
				}
				//检查高度差
				int OfffsetHeight = u.SY - m.SY;
				if( OfffsetHeight != 0 && Math.Abs( u.MidY - m.MidY ) < (u.Height + m.Height) ) {
					AutoLocation a = new AutoLocation( AutoLocation.Near_YOffset );
					a.Offset = OfffsetHeight;
					a.UIModule0 = m;
					a.UIModule1 = u;
					AutoLocationList[ AutoLocationLength ] = a;
					++AutoLocationLength;
				}
			}
		}
	}
	
	//重新搜索尺寸列表
	public void ScanSize( UIModule s )
	{
		AutoLocationLength = 0;
		foreach( MyObject mo in this ) {
		
			if( !(mo is UIModule) ) {
				continue;
			}
			UIModule u = (UIModule)mo;
			if( s == u || !u.isGUIControl() || u.isClientControlPad ) {
				continue;
			}
			//添加长宽
			AutoLocation aw = new AutoLocation( AutoLocation.Near_Width );
			aw.UIModule0 = u;
			aw.Offset = u.Width;
			AutoLocationList[ AutoLocationLength ] = aw;
			++AutoLocationLength;
			
			AutoLocation ah = new AutoLocation( AutoLocation.Near_Height );
			ah.UIModule0 = u;
			ah.Offset = u.Height;
			AutoLocationList[ AutoLocationLength ] = ah;
			++AutoLocationLength;
		}
	}
	
	//获取一个坐标的就近位置
	public void AutoSetLocation( UIModule m, ref int SX, ref int SY )
	{
		int BaseX = m.BaseX;
		int BaseY = m.BaseY;
		
		SX = BaseX;
		SY = BaseY;
		
		SourceUIModule = m;
		
		//初始化为未使用状态
		for( int n = 0; n < AutoLocationLength; ++n ) {
			AutoLocationList[ n ].isUsed = false;
		}
		int SameXValue = 0;
		int SameYValue = 0;
		
		//判断间距
		foreach( MyObject mo in this ) {
		
			if( !(mo is UIModule) ) {
				continue;
			}
			UIModule u = (UIModule)mo;
			if( u == m || !u.isGUIControl() || u.isClientControlPad ) {
				continue;
			}
			//判断宽度间距
			for( int n = 0; n < AutoLocationLength; ++n ) {
				if( AutoLocationList[ n ].NearType != AutoLocation.Near_XOffset && AutoLocationList[ n ].NearType != AutoLocation.Near_YOffset ) {
					continue;
				}
				if( u == AutoLocationList[ n ].UIModule0 ) {
					continue;
				}
				int tSameValue = 0;
				if( m.Width == AutoLocationList[ n ].UIModule1.Width ) ++tSameValue;
				if( m.Height  == AutoLocationList[ n ].UIModule1.Height ) ++tSameValue;
				if( u.Width == AutoLocationList[ n ].UIModule0.Width ) ++tSameValue;
				if( u.Height  == AutoLocationList[ n ].UIModule0.Height ) ++tSameValue;
				
				if( AutoLocationList[ n ].NearType == AutoLocation.Near_XOffset ) {
					int off = AutoLocationList[ n ].Offset;
					if( BaseX > u.SX + off - Offset && BaseX < u.SX + off + Offset ) {
						if( tSameValue > SameXValue ) {
							SameXValue = tSameValue;
							SX = u.SX + off;
							AutoLocationList[ n ].TargetUIModule = u;
							AutoLocationList[ n ].isUsed = true;
						}
					}
				}
				if( AutoLocationList[ n ].NearType == AutoLocation.Near_YOffset ) {
					int off = AutoLocationList[ n ].Offset;
					if( BaseY > u.SY + off - Offset && BaseY < u.SY + off + Offset ) {
						if( tSameValue > SameYValue ) {
							SameYValue = tSameValue;
							SY = u.SY + off;
							AutoLocationList[ n ].TargetUIModule = u;
							AutoLocationList[ n ].isUsed = true;
						}
					}
				}
			}
		}
		//判断单个控件边框对齐
		for( int n = 0; n < AutoLocationLength; ++n ) {
			UIModule u = AutoLocationList[ n ].UIModule0;
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_X ) {
				if( BaseX > u.SX - Offset && BaseX < u.SX + Offset ) {
					SX = u.SX;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_Y ) {
				if( BaseY > u.SY - Offset && BaseY < u.SY + Offset ) {
					SY = u.SY;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
		}
		//判断单个控件边框终点对齐
		for( int n = 0; n < AutoLocationLength; ++n ) {
			UIModule u = AutoLocationList[ n ].UIModule0;
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_XEnd ) {
				if( BaseX + m.Width > u.SX + u.Width - Offset && BaseX + m.Width < u.SX + u.Width + Offset ) {
					SX = u.SX + u.Width - m.Width;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_YEnd ) {
				if( BaseY + m.Height > u.SY + u.Height - Offset && BaseY + m.Height < u.SY + u.Height + Offset ) {
					SY = u.SY + u.Height - m.Height;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
		}
		//判断单个控件边框中心点对齐
		for( int n = 0; n < AutoLocationLength; ++n ) {
			UIModule u = AutoLocationList[ n ].UIModule0;
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_MidY ) {
				if( BaseX + m.Width/2 > u.SX + u.Width/2 - Offset && BaseX + m.Width/2 < u.SX + u.Width/2 + Offset ) {
					SX = u.SX + u.Width/2 - m.Width/2;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_MidY ) {
				if( BaseY + m.Height/2 > u.SY + u.Height/2 - Offset && BaseY + m.Height/2 < u.SY + u.Height/2 + Offset ) {
					SY = u.SY + u.Height/2 - m.Height/2;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
		}
	}
	
	//获取一个坐标的就近位置
	public void AutoSetSize( UIModule m, ref int W, ref int H )
	{
		int BaseWidth = m.BaseWidth;
		int BaseHeight = m.BaseHeight;
		
		W = BaseWidth;
		H = BaseHeight;
		
		SourceUIModule = m;
		
		//初始化为未使用状态
		for( int n = 0; n < AutoLocationLength; ++n ) {
			AutoLocationList[ n ].isUsed = false;
		}
		//判断单个控件边框尺寸
		for( int n = 0; n < AutoLocationLength; ++n ) {
			UIModule u = AutoLocationList[ n ].UIModule0;
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_Width ) {
				if( BaseWidth > AutoLocationList[ n ].Offset - Offset && BaseWidth < AutoLocationList[ n ].Offset + Offset ) {
					W = AutoLocationList[ n ].Offset;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
			if( AutoLocationList[ n ].NearType == AutoLocation.Near_Height ) {
				if( BaseHeight > AutoLocationList[ n ].Offset - Offset && BaseHeight < AutoLocationList[ n ].Offset + Offset ) {
					H = AutoLocationList[ n ].Offset;
					AutoLocationList[ n ].TargetUIModule = u;
					AutoLocationList[ n ].isUsed = true;
				}
			}
		}
	}
	
	//调整模块到网格
	public void AdjToCross()
	{
		foreach( MyObject mo in this ) {
			
			if( mo is HardModule) {
				
				HardModule hm = (HardModule)mo;
				if( hm.PackOwner == null ) {
					hm.ADjToCross();
				}
			}
		}
	}
	
	//==============================================================================================
	
	//鼠标移动事件处理
	public void UserMouseMove( int rX, int rY )
	{
		ShowPanelTime++;
		
		MouseOnBaseX = rX;
		MouseOnBaseY = rY;
		
		bool isMoved = false;
		
		MouseOnPort = null;
		MouseOnIPort = null;
		
		//清空所有指令的移动状态
		foreach( n_MyObject.MyObject mo in this ) {
			if( mo is MyIns ) {
				((MyIns)mo).isMoving = false;
			}
		}
		
		//鼠标在面板上移动
		bool isMouseOnPanel = false;
		
		IterReverse = true;
		foreach( MyObject mo1 in this ) {
			if( !mo1.isVisible() ) {
				continue;
			}
			//当组件没有鼠标按下的时候才会有效, 因为拖动组件的时候如果鼠标移动过快
			//移到面板上会暂时干扰组件的拖动(暂时不响应), 因此需要判断是否有鼠标按下
			//这里边先执行 MouseMove2 是为了先响应面板事件, 并忽略面板下边的组件
			bool mo = !mo1.isMousePress && mo1.MouseMove2( rX, rY );
			isMouseOnPanel |= mo;
			if( mo ) {
				this.MouseOnObject = mo1;
				
				//拖动指令时应继续处理后续的对象序列, 否则下层指令在上层指令上方拖动时无响应
				if( mo1 is MyFileObject || mo1 is n_GNote.GNote ) {
					break;
				}
			}
		}
		IterReverse = false;
		
		if( isMouseOnPanel ) {
			return;
		}
		//鼠标在控件上移动
		this.MouseOnObject = null;
		
		IterReverse = true;
		foreach( MyObject mo in this ) {
			if( !mo.isVisible() ) {
				continue;
			}
			mo.isMoved = false;
			int MoveType = mo.MouseMove1( rX, rY );
			if( MoveType == 0 ) {
				continue;
			}
			this.MouseOnObject = mo;
			
			if( MoveType == 1 ) {
				if( mo is MyFileObject || mo is n_GNote.GNote ) {
					
					//这里是避免鼠标在参数调节框上移动时(点击状态下)调节参数, 不受附近模块影响 (有问题未启用)
					break;
				}
			}
			if( MoveType == 2 ) {
				mo.isMoved = true;
				isMoved = true;
				if( mo is MyFileObject || mo is n_GNote.GNote ) {
					break;
				}
			}
			else {
				//...
			}
		}
		IterReverse = false;
		
		//如果有被拖动的组件,进行组件碰撞处理
		if( isMoved ) {
			NeedDrawLineMap = true;
			foreach( MyObject mo in this ) {
				if( !mo.isMoved ) {
					continue;
				}
				mo.isMoved = false;
				HitModule( mo );
			}
		}
		n_EXP.EXP.Translate = false;
	}
	
	//鼠标按下事件
	public bool UserMouseDown( int rX, int rY )
	{
		if( MyObject.PasteMoveTime != 0 ) {
			MyObject.PasteMoveTime = 0;
		}
		
		if( SelectIPort == null && SelectPort == null ) {//&& !SkipFirstShowPanel ) {
			ShowPanelTime = 0;
		}
		else {
			ShowPanelTime = 100;
			
			//不添加新指令
			ImagePanel.MoveTick = ImagePanel.MaxMoveTick;
		}
		
		bool isInModule = false;
		
		IterReverse = true;
		
		foreach( MyObject mo in this ) {
		
			if( !mo.isVisible() ) {
				continue;
			}
			if( mo.MouseDown2( rX, rY ) ) {
				isInModule = true;
			}
		}
		if( !isInModule ) {
			foreach( MyObject mo in this ) {
				if( !mo.isVisible() ) {
					continue;
				}
				if( mo.MouseDown1( rX, rY ) ) {
					isInModule = true;
					
					//这里可以防止重叠的指令同时被拖动
					break;
				}
			}
		}
		//判断是否需要给当前点添加
		if( !isInModule && SelectPort != null ) {
			if( SelectPort.MidPortIndex == -1 ) {
				SelectPort.MidPortIndex = GPanel.myMidPortList.AddList();
			}
			bool re = false;
			if( n_HardModule.Port.C_Rol == 0 ) {
				int ttX = (rX) / 10 * 10;
				int ttY = (rY) / 10 * 10;
				re = GPanel.myMidPortList.AddPort( SelectPort.MidPortIndex, ttX, ttY );
			}
			else {
				re = GPanel.myMidPortList.AddPort( SelectPort.MidPortIndex, rX, rY );
			}
			if( re ) {
				SelectPort = null;
			}
		}
		
		//取消所有模块的高亮
		bool ExistHighLight = false;
		if( !isInModule ) {
			foreach( MyObject mo in this ) {
				if( mo is n_MyFileObject.MyFileObject || mo is n_GVar.GVar || mo is n_GNote.GNote ) {
					ExistHighLight |= mo.isHighLight;
			 		mo.isHighLight = false;
			 	}
			}
		}
		IterReverse = false;
		
		if( ExistHighLight ) {
			ImagePanel.MoveTick = ImagePanel.MaxMoveTick;
		}
		
		return isInModule;
	}
	
	//鼠标松开事件
	public void UserMouseUp( int rX, int rY )
	{
		if( MouseOnObject != null ) {
			MouseOnObject.isHighLight = false;
		}
		if( SelectIPort == null && SelectPort == null && ShowPanelTime < ShowPanelMaxTime && MouseOnObject != null ) {
			if( !MouseOnObject.IgnoreHighLight ) {
				MouseOnObject.isHighLight = true;
			}
		}
		if( MouseOnObject != null ) {
			MouseOnObject.IgnoreHighLight = false;
		}
		SourceUIModule = null;
		
		IterReverse = true;
		
		foreach( MyObject mo in this ) {
			if( !mo.isVisible() ) {
				continue;
			}
			mo.MouseUp2( rX, rY );
		}
		foreach( MyObject mo in this ) {
			if( !mo.isVisible() ) {
				continue;
			}
			mo.MouseUp1( rX, rY );
		}
		IterReverse = false;
	}
	
	//==============================================================================================
	
	//按键按下时
	public void UserKeyDown( Keys k )
	{
		foreach( MyObject mo in this ) {
			if( mo is HardModule ) {
				HardModule hm = (HardModule)mo;
				hm.MyKeyDown( k );
			}
		}
	}
	
	//按键松开时
	public void UserKeyUp( Keys k )
	{
		foreach( MyObject mo in this ) {
			if( mo is HardModule ) {
				HardModule hm = (HardModule)mo;
				hm.MyKeyUp( k );
			}
		}
	}
	
	//==============================================================================================
	
	//根据输入的组件坐标进行组件遍历,找出所有碰撞的组件,调整其坐标,并递归调用此函数
	void HitModule( MyObject sm )
	{
		if( GPanel.DisableHit || sm == null || sm.ignoreHit || sm.CanFloat || !sm.isVisible() ) {
			return;
		}
		foreach( MyObject mo in this ) {
			
			//拖动封包模块时, 由于其他封包也同步拖动, 所以不需要碰撞判断 (否则会递归)
			if( sm is HardModule && ((HardModule)sm).PackOwner != null && mo is HardModule && ((HardModule)mo).PackOwner != null  ) {
				continue;
			}
			
			if( mo == sm || mo.ignoreHit || mo.CanFloat || !mo.isVisible() ) {
				continue;
			}
			//如果发生碰撞, 就调整被碰组件的坐标, 并递归调用此函数
			if( AisHitB( sm, mo ) ) {
				HitModule( mo );
			}
		}
	}
	
	//碰撞检测
	bool AisHitB( MyObject m1, MyObject m2 )
	{
		int dX = ( m1.Width + m2.Width ) / 2 - Math.Abs( m1.MidX - m2.MidX );
		int dY = ( m1.Height + m2.Height ) / 2 - Math.Abs( m1.MidY - m2.MidY );
		if( dX > 0 && dY > 0 ) {
			if( dX < dY ) {
				if( m2.MidX < m1.MidX ) {
					dX = -dX;
				}
				m2.SX += dX;
				if( m2 is HardModule ) {
					((HardModule)m2).PackModuleMove( dX, 0 );
				}
			}
			else {
				if( m2.MidY < m1.MidY ) {
					dY = -dY;
				}
				m2.SY += dY;
				if( m2 is HardModule ) {
					((HardModule)m2).PackModuleMove( 0, dY );
				}
			}
			m2.RefreshPanelLocation();
			return true;
		}
		else {
			return false;
		}
	}
}
//自动定位类
public class AutoLocation
{
	public bool isUsed;
	public int Offset;
	public UIModule UIModule0;
	public UIModule UIModule1;
	public UIModule TargetUIModule;
	
	public int NearType;
	public const int Near_None = 0;
	public const int Near_X = 2;
	public const int Near_Y = 3;
	public const int Near_XEnd = 4;
	public const int Near_YEnd = 5;
	public const int Near_XOffset = 6;
	public const int Near_YOffset = 7;
	public const int Near_Width = 8;
	public const int Near_Height = 9;
	public const int Near_MidX = 10;
	public const int Near_MidY = 11;
	
	//构造函数
	public AutoLocation( int vNearType )
	{
		NearType = vNearType;
		Offset = 0;
		UIModule0 = null;
		UIModule1 = null;
		isUsed = false;
	}
}
}



